//model.rs
//存放公用结构体和枚举体

/// 统一对外公开的 Token 结构u
#[derive(Debug, Clone, PartialEq)]
pub struct Token {
    pub line: usize,
    pub kind: TokenKind,
    pub text: String,
}

#[derive(Debug, Clone, PartialEq, Copy)]
pub enum TokenKind {
    // 关键字
    Const, Int, Void, If, Else, While, Break, Continue, Return,

    // 标识符 & 字面量
    Ident,
    IntegerConst, // ← 不再带值

    // 运算符
    Plus, Minus, Mul, Div, Mod,
    Assign, Eq, Neq, Lt, Le, Gt, Ge, Not, And, Or,

    // 分界符
    LParen, RParen, LBrack, RBrack, LBrace, RBrace, Comma, Semicolon,
}

// 纯 TokenKind AST
#[derive(Debug, Clone, PartialEq)]
pub enum AstNode {
    // 单个 Token 节点
    Token(TokenKind, Option<String>), // 添加原始文本信息
    // 序列节点，用于表示如 {stmt1, stmt2, ...}
    Sequence(Vec<AstNode>),
    // 复合节点，用于表示有明确结构的语法成分
    Node {
        kind: TokenKind, // 用一个 TokenKind 代表该节点类型，如 Node{kind: Int, ...} 表示一个 BType 节点
        children: Vec<AstNode>,
        token_start_idx: usize, // 记录节点在 token 流中的起始位置
    },
}

// 为 AstNode 实现一个便捷方法
impl AstNode {
    pub fn get_kind(&self) -> TokenKind {
        match self {
            AstNode::Token(kind, _) => *kind,
            AstNode::Node { kind, .. } => *kind,
            AstNode::Sequence(_) => TokenKind::LBrace, // 默认
        }
    }
}

/// 物理行表示，包含该行的所有token和缩进信息
#[derive(Debug, Clone, Default)]
pub struct PhysicalLine {
    pub tokens: Vec<Token>,      // 该行包含的所有token
    pub indent_level: usize,     // 缩进级别
}

/// 简化的语句表示，用于格式化
#[derive(Debug, Clone)]
pub struct SimplifiedStmt {
    pub stmt_type: StmtType,
    pub indent_level: usize,
    pub tokens: Vec<TokenKind>,
    pub text: String,
}

/// 语句类型枚举
#[derive(Debug, Clone, PartialEq)]
pub enum StmtType {
    /// 声明语句
    Decl,
    /// 赋值语句
    Assign,
    /// 控制语句 (if, while等)
    Control,
    /// 返回语句
    Return,
    /// 函数调用语句
    Call,
    /// 表达式语句
    Expr,
    /// 代码块开始
    BlockStart,
    /// 代码块结束
    BlockEnd,
    /// 空语句
    Empty,
    /// Break语句
    Break,
    /// Continue语句
    Continue,
    /// 一般语句
    Statement,
    /// 函数定义
    FuncDefinition,
}
